#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>


#undef IMAX

#define COMPSIZE 1
#define MAX(a,b) (a<b? b:a)

#ifdef DOUBLE
#define FLOAT double
#else
#define FLOAT float
#endif

#define SCALAR double
#define SCALAR_SUFFIX d
#define EIGEN_NO_DEBUG
#define EIGEN_DONT_PARALLELIZE
#include "blas_level1_impl.h"
#include "blas_level1_real_impl.h"


int main(int argc, char *argv[]){

  FLOAT *x,*y;
  FLOAT alpha[2] = {2.0, 2.0};
  int m, i;
  int inc_x=1;
  int inc_y=1;
  int loops = 1;
  int l;
  char *p;

  int from =   1;
  int to   = 200;
  int step =   1;

  struct timeval start, stop;
  double time1,timeg;

  argc--;argv++;

  if (argc > 0) { from     = atol(*argv);		argc--; argv++;}
  if (argc > 0) { to       = MAX(atol(*argv), from);	argc--; argv++;}
  if (argc > 0) { step     = atol(*argv);		argc--; argv++;}

  if ((p = getenv("OPENBLAS_LOOPS")))  loops = atoi(p);
  if ((p = getenv("OPENBLAS_INCX")))   inc_x = atoi(p);

  fprintf(stderr, "From : %3d  To : %3d Step = %3d Inc_x = %d Loops = %d\n", from, to, step,inc_x,loops);

  if (( x = (FLOAT *)malloc(sizeof(FLOAT) * to * abs(inc_x) * COMPSIZE)) == NULL){
    fprintf(stderr,"Out of Memory!!\n");exit(1);
  }

  if (( y = (FLOAT *)malloc(sizeof(FLOAT) * to * abs(inc_y) * COMPSIZE)) == NULL){
    fprintf(stderr,"Out of Memory!!\n");exit(1);
  }

  srandom(getpid());

  fprintf(stderr, "   SIZE       Flops\n");

  for(m = from; m <= to; m += step)
  {

   timeg=0;

   fprintf(stderr, " %6d : ", (int)m);


   for (l=0; l<loops; l++)
   {

   	for(i = 0; i < m * COMPSIZE * abs(inc_x); i++){
			x[i] = ((FLOAT) rand() / (FLOAT) RAND_MAX) - 0.5;
   	}

     for(i = 0; i < m * COMPSIZE * abs(inc_y); i++){
			y[i] = ((FLOAT) rand() / (FLOAT) RAND_MAX) - 0.5;
   	}

    	gettimeofday( &start, (struct timezone *)0);

    	// eigen_amax (&m, x, &inc_x);
      // eigen_amin((int *)&m, x, &inc_x);
      // double result = eigen_dot((int *)&m, x, &inc_x, y, &inc_y);
      double result = eigen_nrm2((int *)&m, x, &inc_x);
      // eigen_axpy((int *)&m, alpha, x, &inc_x, y, &inc_y);
      // eigen_asum((int *)&m, x, &inc_x);

    	gettimeofday( &stop, (struct timezone *)0);

    	time1 = (double)(stop.tv_sec - start.tv_sec) + (double)((stop.tv_usec - start.tv_usec)) * 1.e-6;
      timeg += time1;

      fprintf(stderr," r=%10.2f  ",result);
    }

    timeg /= loops;

    fprintf(stderr,
	    " %10.2f MFlops %10.9f sec\n",
	    COMPSIZE * COMPSIZE * 2. * (double)m / timeg * 1.e-6, timeg);

  }

  return 0;
}
